package com.cy.controller;

import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import cn.hutool.poi.excel.StyleSet;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cy.common.entity.Result;
import com.cy.common.exception.CommonException;
import com.cy.common.utils.JwtUtils;
import com.cy.mapper.UserRoleMapper;
import com.cy.pojo.*;
import com.cy.pojo.vo.*;
import com.cy.service.AcademyService;
import com.cy.service.AchievementService;
import com.cy.service.DepartmentService;
import com.cy.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.SheetUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author 残影
 * @description 科研成果信息
 * @date 2022-04-19
 */
@RestController
@RequestMapping("/achievement")
@Api(tags = "科研成果信息模块")
public class AchievementController {
    @Autowired
    private AchievementService achievementService;
    @Autowired
    private UserService userService;
    @Autowired
    private DepartmentService departmentService;
    @Autowired
    private AcademyService academyService;

    /**
     * 根据ID查询科研成果信息
     */
    @GetMapping("{id}")
    @ApiOperation("根据ID查询科研成果信息")
    public Result findById(@PathVariable Integer id) {
        Achievement achievement = achievementService.getById(id);
        if (achievement != null) {
            return Result.ok("查询科研成果信息成功", achievement);
        } else {
            return Result.failed(201, "没有该科研成果信息");
        }
    }

    /**
     * 分页查询科研成果信息
     */
    @ApiOperation("分页查询科研成果信息")
    @GetMapping("/list")
    public Result list(SearchAchievement searchAchievement, HttpServletRequest request) {
        //分页构造器
        Page<Achievement> buildPage = new Page<>(searchAchievement.getPage(), searchAchievement.getLimit());
        //条件构造器
        QueryWrapper<Achievement> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(searchAchievement.getName())) {
            queryWrapper.like("achievement_name", searchAchievement.getName());
        }
        if (ObjectUtils.isNotEmpty(searchAchievement.getDepartmentId())) {
            queryWrapper.eq("department_id", searchAchievement.getDepartmentId());
        }
        if (ObjectUtils.isNotEmpty(searchAchievement.getAcademyId())) {
            queryWrapper.eq("academy_id", searchAchievement.getAcademyId());
        }
        if (ObjectUtils.isNotEmpty(searchAchievement.getAchievementType())) {
            queryWrapper.eq("achievement_type", searchAchievement.getAchievementType());
        }

        IPage<Achievement> pageList = achievementService.page(buildPage, queryWrapper);

        List<AchievementQueryVo> achievementQueryVoArrayList = new ArrayList<>();
        List<Department> departmentList = departmentService.list();
        List<Academy> academyList = academyService.list();
        List<Achievement> achievementList = pageList.getRecords();
        achievementList.forEach(achievement -> {
            AchievementQueryVo achievementQueryVo = new AchievementQueryVo();
            BeanUtils.copyProperties(achievement, achievementQueryVo);
            departmentList.forEach(department -> {
                if (department.getDepartmentId() == achievement.getDepartmentId()) {
                    achievementQueryVo.setDepartmentName(department.getDepartmentName());
                }
            });
            academyList.forEach(academy -> {
                if (academy.getAcademyId() == achievement.getAcademyId()) {
                    achievementQueryVo.setAcademyName(academy.getAcademyName());
                }
            });
            achievementQueryVoArrayList.add(achievementQueryVo);
        });
        return Result.ok("查询成功", achievementQueryVoArrayList).put("total", pageList.getTotal());
    }

    /**
     * 导出科研成果信息
     */
    @ApiOperation("导出科研成果信息")
    @GetMapping("/export")
    public void export(SearchAchievement searchAchievement, HttpServletRequest request, HttpServletResponse response) throws IOException {
        //分页构造器
        Page<Achievement> buildPage = new Page<>(searchAchievement.getPage(), searchAchievement.getLimit());
        //条件构造器
        QueryWrapper<Achievement> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(searchAchievement.getName())) {
            queryWrapper.like("achievement_name", searchAchievement.getName());
        }
        if (ObjectUtils.isNotEmpty(searchAchievement.getDepartmentId())) {
            queryWrapper.eq("department_id", searchAchievement.getDepartmentId());
        }
        if (ObjectUtils.isNotEmpty(searchAchievement.getAcademyId())) {
            queryWrapper.eq("academy_id", searchAchievement.getAcademyId());
        }
        if (ObjectUtils.isNotEmpty(searchAchievement.getAchievementType())) {
            queryWrapper.eq("achievement_type", searchAchievement.getAchievementType());
        }

        IPage<Achievement> pageList = achievementService.page(buildPage, queryWrapper);

        List<AchievementQueryVo> achievementQueryVoArrayList = new ArrayList<>();
        List<Department> departmentList = departmentService.list();
        List<Academy> academyList = academyService.list();
        List<Achievement> achievementList = pageList.getRecords();
        achievementList.forEach(achievement -> {
            AchievementQueryVo achievementQueryVo = new AchievementQueryVo();
            BeanUtils.copyProperties(achievement, achievementQueryVo);
            departmentList.forEach(department -> {
                if (department.getDepartmentId() == achievement.getDepartmentId()) {
                    achievementQueryVo.setDepartmentName(department.getDepartmentName());
                }
            });
            academyList.forEach(academy -> {
                if (academy.getAcademyId() == achievement.getAcademyId()) {
                    achievementQueryVo.setAcademyName(academy.getAcademyName());
                }
            });
            achievementQueryVoArrayList.add(achievementQueryVo);
        });

        List<ExportAchievementVo> exportAchievementVoList = new ArrayList<>();
        if (achievementQueryVoArrayList.size() == 0) {
            throw new CommonException("没有可以导出的数据");
        }
        for (int i = 0; i < achievementQueryVoArrayList.size(); i++) {
            ExportAchievementVo exportAchievementVo = new ExportAchievementVo();
            BeanUtils.copyProperties(achievementQueryVoArrayList.get(i), exportAchievementVo);
            if (achievementQueryVoArrayList.get(i).getAchievementType() == 0) {
                exportAchievementVo.setAchievementTypeName("专利");
            } else if (achievementQueryVoArrayList.get(i).getAchievementType() == 1) {
                exportAchievementVo.setAchievementTypeName("论文");
            } else if (achievementQueryVoArrayList.get(i).getAchievementType() == 2) {
                exportAchievementVo.setAchievementTypeName("获奖");
            } else if (achievementQueryVoArrayList.get(i).getAchievementType() == 3) {
                exportAchievementVo.setAchievementTypeName("科研项目");
            } else if (achievementQueryVoArrayList.get(i).getAchievementType() == 4) {
                exportAchievementVo.setAchievementTypeName("著作");
            } else {
                exportAchievementVo.setAchievementTypeName("其他成果");
            }
            exportAchievementVo.setId((i + 1L));
            exportAchievementVoList.add(exportAchievementVo);
        }
        // 通过工具类创建writer，默认创建xls格式
        ExcelWriter writer = ExcelUtil.getWriter();
        //自定义标题别名
        writer.addHeaderAlias("id", "序号");
        writer.addHeaderAlias("achievementName", "名称");
        writer.addHeaderAlias("academyName", "学院");
        writer.addHeaderAlias("departmentName", "专业");
        writer.addHeaderAlias("achievementTypeName", "类型");
        writer.addHeaderAlias("createBy", "创建人");
        writer.addHeaderAlias("createTime", "创建时间");
        writer.addHeaderAlias("updateBy", "修改人");
        writer.addHeaderAlias("updateTime", "修改时间");
        // 一次性写出内容，使用默认样式，强制输出标题
        writer.write(exportAchievementVoList, true);

        StyleSet styleSet = writer.getStyleSet();
        Font font = writer.createFont();
        font.setColor(IndexedColors.VIOLET.index);
        font.setBold(true);
        font.setFontHeightInPoints((short) 12);
        //重点，设置中文字体
        font.setFontName("宋体");
        styleSet.getHeadCellStyle().setFont(font);
        int columnCount = writer.getColumnCount();
        for (int i = 0; i < columnCount; ++i) {
            double width = SheetUtil.getColumnWidth(writer.getSheet(), i, false);
            if (width != -1.0D) {
                width *= 256.0D;
                //此处可以适当调整，调整列空白处宽度
                width += 220D;
                writer.setColumnWidth(i, Math.toIntExact(Math.round(width / 256D)));
            }
        }

        //out为OutputStream，需要写出到的目标流

        //response为HttpServletResponse对象
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        //test.xls是弹出下载对话框的文件名，不能为中文，中文请自行编码
        response.setHeader("Content-Disposition", "attachment;filename=achievement.xls");
        ServletOutputStream out = response.getOutputStream();

        writer.flush(out, true);
        // 关闭writer，释放内存
        writer.close();
        //此处记得关闭输出Servlet流
        IoUtil.close(out);
    }

    /**
     * 保存科研成果信息
     */
    @PostMapping
    @ApiOperation("保存科研成果信息")
    public Result save(@RequestBody AchievementVo achievementVo, HttpServletRequest request) {
        Long currentUserId = JwtUtils.getUserIdByRequest(request);
        User currentUser = userService.getById(currentUserId);

        Achievement achievement = new Achievement();
        BeanUtils.copyProperties(achievementVo, achievement);

        achievement.setCreateTime(new Date());
        achievement.setUpdateTime(new Date());
        achievement.setCreateBy(currentUser.getNickName());
        achievement.setUpdateBy(currentUser.getNickName());
        achievement.setStatus(0L);
        boolean b = achievementService.save(achievement);
        if (b) {
            return Result.ok("保存用户科研成果信息成功", achievement);
        } else {
            return Result.failed("保存科研成果信息失败");
        }
    }

    /**
     * 修改科研成果信息
     */
    @PutMapping("{id}")
    @ApiOperation("修改科研成果信息")
    public Result update(@RequestBody AchievementVo achievementVo, @PathVariable Long id, HttpServletRequest request) {
        Long currentUserId = JwtUtils.getUserIdByRequest(request);
        User currentUser = userService.getById(currentUserId);

        Achievement achievement = achievementService.getById(id);
        if (ObjectUtils.isEmpty(achievement)) {
            throw new CommonException("科研成果信息不存在");
        }
        if (currentUser.getUserType() != 1 && !achievement.getCreateBy().equals(currentUser.getNickName())) {
            throw new CommonException("只允许作者和管理员进行修改");
        }
        BeanUtils.copyProperties(achievementVo, achievement);
        achievement.setUpdateTime(new Date());
        achievement.setUpdateBy(currentUser.getNickName());

        boolean b = achievementService.saveOrUpdate(achievement);
        if (b) {
            return Result.ok("修改科研成果信息成功", achievement);
        } else {
            return Result.failed("修改科研成果信息失败");
        }
    }


    /**
     * 审核科研成果信息
     */
    @PutMapping("/check/{id}")
    @ApiOperation("审核科研成果信息")
    public Result check(@PathVariable Long id) {
        Achievement achievement = achievementService.getById(id);
        if (ObjectUtils.isEmpty(achievement)) {
            throw new CommonException("科研成果信息不存在");
        }
        achievement.setStatus(1L);
        boolean b = achievementService.saveOrUpdate(achievement);
        if (b) {
            return Result.ok("审核科研成果信息成功", achievement);
        } else {
            return Result.failed("审核科研成果信息失败");
        }
    }

    /**
     * 删除科研成果信息
     */
    @DeleteMapping("{id}")
    @ApiOperation("删除科研成果信息")
    public Result delete(@PathVariable Long id, HttpServletRequest request) {
        Long currentUserId = JwtUtils.getUserIdByRequest(request);
        User currentUser = userService.getById(currentUserId);

        Achievement achievement = achievementService.getById(id);
        if (currentUser.getUserType() != 1 && !achievement.getCreateBy().equals(currentUser.getNickName())) {
            throw new CommonException("只允许作者和管理员进行删除");
        }
        boolean b = achievementService.removeById(id);
        if (b) {
            return Result.ok("删除科研成果信息成功");
        } else {
            return Result.failed("删除科研成果信息失败");
        }
    }
}
